[IA64] Prevent rfi emulation with double un-cover
authorAlex Williamson <alex.williamson@hp.com>
Mon, 4 Jun 2007 20:03:42 +0000 (14:03 -0600)
committerAlex Williamson <alex.williamson@hp.com>
Mon, 4 Jun 2007 20:03:42 +0000 (14:03 -0600)
Recently (CS 13436) rfi hyperprivop was simplified.  But as a consequence
rfi emulation with double un-cover is not possible anymore.

Comment priv_rfi and forbid rfi emulation with double un-cover.

Signed-off-by: Tristan Gingold <tgingold@free.fr>
xen/arch/ia64/xen/hyperprivop.S
xen/arch/ia64/xen/privop.c

index 2fe754cb86d67b32d9d34a7c2f055db08dde0475..58269fc110a3714f574928818cb0598b63ce1bff 100644 (file)
@@ -1029,8 +1029,22 @@ ENTRY(slow_vcpu_rfi)
        ld8 r22=[r22];;
        tbit.z p6,p0=r22,63
 (p6)   br.spnt.few dispatch_break_fault ;;
-       // if vips is valid, discard current register frame
-       // don't need dorfirfi any more
+       // If vifs.v is set, we have two IFS to consider:
+       // * the guest IFS
+       // * the hypervisor IFS (validated by cover)
+       // Because IFS is copied to CFM and is used to adjust AR.BSP,
+       // virtualization of rfi is not easy.
+       // Previously there was a two steps method (a first rfi jumped to
+       // a stub which performed a new rfi).
+       // This new method discards the RS before executing the hypervisor
+       // cover.  After cover, IFS.IFM will be zero.  This IFS would simply
+       // clear CFM but not modifying AR.BSP.  Therefore the guest IFS can
+       // be used instead and there is no need of a second rfi.
+       // Discarding the RS with the following alloc instruction just clears
+       // CFM, which is safe because rfi will overwrite it.
+       // There is a drawback: because the RS must be discarded before
+       // executing C code, emulation of rfi must go through an hyperprivop
+       // and not through normal instruction decoding.
        alloc r22=ar.pfs,0,0,0,0
        br.spnt.few dispatch_break_fault
        ;;
index 559c3e44ea1eeff28661d353c68116e57209f08d..8ca6e49b8b75ce88f5ca6895b21355bd2913aae2 100644 (file)
@@ -31,6 +31,15 @@ Privileged operation emulation routines
 
 static IA64FAULT priv_rfi(VCPU * vcpu, INST64 inst)
 {
+       REGS *regs = vcpu_regs(vcpu);
+       if (PSCB(vcpu, ifs) > 0x8000000000000000UL
+           && regs->cr_ifs > 0x8000000000000000UL) {
+               panic_domain(regs,
+                            "rfi emulation with double uncover is "
+                            "impossible - use hyperprivop\n"
+                            " ip=0x%lx vifs=0x%lx ifs=0x%lx\n",
+                            regs->cr_iip, PSCB(vcpu, ifs), regs->cr_ifs);
+       }
        return vcpu_rfi(vcpu);
 }